package com.globallogic.training.javase.basics;

import java.util.Scanner;

/**
* This program returns the day of the week for the input date.
* @version 1.2 2013-04-04
* @author Ivan Moisiienko
*/

public class CalendarSeeker {

	static final int DAYS_IN_YEAR = 365;
	static final int DAYS_IN_LEAP_YEAR = 366;
	static final int DAYS_IN_WEEK = 7;
	static final int START_YEAR = 1900;
	static final String PROMPT_MESSAGE
		= "Enter any date in format dd <Month> YYYY "
		+ "[for example, 10 October 2010]:";
	static final String OUTPUT_MESSAGE = "The day of week is ";

	public enum Month {
		JANUARY(31), FEBRUARY(28), MARCH(31), APRIL(30),
		MAY(31), JUNE(30), JULY(31), AUGUST(31), SEPTEMBER(30),
		OCTOBER(31), NOVEMBER(30), DECEMBER(31);

		int numberOfDays;
		int monthNumber;

		Month(int number) {
			this.numberOfDays = number;
		}

		int getNumberOfDays() {
			return numberOfDays;
		}

		boolean isValidDay(int day, boolean isLeapYear) {
			if (day <= 0) {
				return false;
			}

			if (equals(Month.FEBRUARY) && isLeapYear) {

				if (day > numberOfDays + 1) {
					return false;
				} else {
					return true;
				}
			}

			if (day > numberOfDays) {
				return false;
			}

			return true;
		}

	};

	public enum DayOfWeek {
		SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
		THURSDAY, FRIDAY, SATURDAY;

		static DayOfWeek getName(int number)
		{
			return values()[number % 7];
		}
	};

	public static void main(String[] args){

		int inputYear;
		Month inputMonth;
		int inputDay;

		do {
			String[] input = provideInput();
			inputDay = Integer.parseInt(input[0]);
			inputMonth = Month.valueOf(input[1].toUpperCase());
			inputYear = Integer.parseInt(input[2]);
		} while (!inputMonth.isValidDay(inputDay, isLeapYear(inputYear)));

		DayOfWeek result = getDayOfWeek(inputYear, inputMonth, inputDay);
		System.out.println(OUTPUT_MESSAGE + result);
	}

	static String[] provideInput() {
		Scanner in = new Scanner (System.in);
		System.out.print(PROMPT_MESSAGE);
		String[] result = in.nextLine().trim().replaceAll("\\s+", " ").split(" ");

		return result;
	}

	static boolean isLeapYear(int year) {
  		if (year % 400 == 0) {
    		return true;
  		} else if (year % 100 == 0) {
  		  	return false;
  		} else if (year % 4 == 0) {
    		return true;
  		} else {
    		return false;
  		}
	}


	static DayOfWeek getDayOfWeek(int year, Month month, int days) {
		int daysFromStartOfCurrentYear = days;

		for (Month m : Month.values()) {
			if(m.equals(month)) {
					break;
			}

			if (Month.FEBRUARY.equals(m) && isLeapYear(year)) {
				daysFromStartOfCurrentYear++;
			}
			daysFromStartOfCurrentYear += m.getNumberOfDays();
		}

		if (year >= START_YEAR) {

			for (int y = START_YEAR; y < year; y++) {
				if (isLeapYear(y)) {
					daysFromStartOfCurrentYear += DAYS_IN_LEAP_YEAR;
				} else {
					daysFromStartOfCurrentYear += DAYS_IN_YEAR;
				}
			}
		} else {
			for (int y = year; y < START_YEAR; y++) {
				if (isLeapYear(y)) {
					daysFromStartOfCurrentYear -= DAYS_IN_LEAP_YEAR;
				} else {
					daysFromStartOfCurrentYear -= DAYS_IN_YEAR;
				}
			daysFromStartOfCurrentYear = daysFromStartOfCurrentYear % 7 + 7;
			}
		}

		return DayOfWeek.getName(daysFromStartOfCurrentYear % DAYS_IN_WEEK);
	}

}